home *** CD-ROM | disk | FTP | other *** search
/ Gold Medal Software 1 / Gold Medal Software Volume 1 (Gold Medal) (1994).iso / prog / pcl4c40.arj / XYPACKET.C < prev    next >
Encoding:
C/C++ Source or Header  |  1993-09-22  |  9.8 KB  |  323 lines

  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <fcntl.h>
  4. #include <io.h>
  5. #include <sys\types.h>
  6. #include <sys\stat.h>
  7.  
  8. #include "pcl4c.h"
  9. #include "term.h"
  10. #include "crc.h"
  11. #include "ascii.h"
  12. #include "term_io.h"
  13. #include "term.cfg"
  14.  
  15. #define DEBUG 0
  16. #define FALSE 0
  17. #define TRUE !FALSE
  18.  
  19. #define MAXTRY 5
  20. #define LIMIT 20
  21.  
  22. void PacketError(int ,int ,int ,char *);
  23.  
  24. int TxPacket(
  25.    int Port,            /* COM port [0..3] */
  26.    int PacketNbr,       /* Packet # to send */
  27.    int PacketSize,      /* Packet size ( must be 128 or 1024 ) */
  28.    char Buffer[],       /* Data buffer */
  29.    char NCGchar)        /* NAK, 'C', or 'G' */
  30. {int  i;
  31.  int Code;
  32.  unsigned short CheckSum;
  33.  int Attempt;
  34.  int PacketType;
  35.  char temp[81];
  36.  /* begin */
  37. #if DEBUG
  38. printf("[TxP: COM%d PacketNbr=%d PacketSize=%d NCGchar=%c]",
  39.     1+Port,PacketNbr,PacketSize,NCGchar);
  40. #endif
  41.  /* better be 128 or 1024 packet length */
  42.  if(PacketSize==1024) PacketType = STX;
  43.  else PacketType = SOH;
  44.  PacketNbr &= 0x00ff;
  45.  /* make up to MAXTRY attempts to send this packet */
  46.  for(Attempt=1;Attempt<=MAXTRY;Attempt++)
  47.      {/* send SOH/STX  */
  48.       Code = PutChar(Port,(char)PacketType);
  49.       /* send packet # */
  50.       Code = PutChar(Port,(char)PacketNbr);
  51.       /* send 1's complement of packet */
  52.       Code = PutChar(Port,(char)(255-PacketNbr));
  53.       /* send data */
  54.       CheckSum = 0;
  55.       for(i=0;i<PacketSize;i++)
  56.           {Code = PutChar(Port,Buffer[i]);
  57.            if(NCGchar==NAK) CheckSum += Buffer[i];
  58.            else CheckSum = UpdateCRC(CheckSum, Buffer[i]);
  59.           }
  60.       /* send checksum */
  61.       if(NCGchar==NAK)
  62.           {Code = PutChar(Port,(char)(CheckSum & 0x00ff) );
  63.           }
  64.       else
  65.           {Code = PutChar(Port, (char)((CheckSum>>8) & 0x00ff) );
  66.            Code = PutChar(Port, (char)(CheckSum & 0x00ff) );
  67.           }
  68.       /* no ACK to wait for if 'G' */
  69.       if(NCGchar=='G')
  70.          {if(PacketNbr==0) SioDelay(SHORT_WAIT*ONE_SECOND/2);
  71.           return(TRUE);
  72.          }
  73.       /* wait for receivers ACK */
  74.       Code = GetChar(Port,LONG_WAIT*ONE_SECOND);
  75.       if((char)Code==CAN)
  76.           {DisplayLine("*** Canceled by REMOTE ***",NULL,0);
  77.            return(FALSE);
  78.           }
  79.       if((char)Code==ACK) return(TRUE);
  80.       if((char)Code!=NAK)
  81.           {PacketError(Port,PacketNbr,Attempt,"Out of sync");
  82.            return(FALSE);
  83.           }
  84.       /* Attempt again */
  85.      }/* end -- for(Attempt) */
  86.  /* can't send packet ! */
  87.  SayError(Port,"packet timeout (3 NAKs)");
  88.  return(FALSE);
  89. } /* end -- TxPacket */
  90.  
  91. int RxPacket(
  92.    int Port,            /* COM port [0..3] */
  93.    int PacketNbr,       /* Packet # expected */
  94.    int *PacketSizePtr,  /* Pointer to PacketSize received ( 128 or 1024) */
  95.    char Buffer[],       /* 1024 byte data buffer */
  96.    char NCGchar,        /* NAK, C, or G */
  97.    int *EOTptr)         /* Pointer to EOT flag */
  98. {int i;
  99.  int Code;
  100.  int Attempt;
  101.  int RxPacketNbr;
  102.  int RxPacketNbrComp;
  103.  unsigned short CheckSum;
  104.  unsigned short RxCheckSum;
  105.  unsigned short RxCheckSum1, RxCheckSum2;
  106.  /*char PacketType;*/
  107.  char temp[81];
  108.  /* begin */
  109. #if DEBUG
  110. printf("[RxP: COM%d PacketNbr=%d NCGchar=%c EOTflag=%d]",
  111.     1+Port,PacketNbr,NCGchar,*EOTptr);
  112. #endif
  113.  PacketNbr &= 0x00ff;
  114.  for(Attempt=1;Attempt<=MAXTRY;Attempt++)
  115.      {/* wait for SOH / STX */
  116.       Code = GetChar(Port,SHORT_WAIT*ONE_SECOND);
  117.       if(Code==-1)
  118.           {PacketError(Port,PacketNbr,Attempt,"timed out waiting for SOH/STX");
  119.            return(FALSE);
  120.           }
  121.       switch((char)Code)
  122.           {
  123.            case SOH:
  124.                /* 128 byte buffer incoming */
  125.                /*PacketType = SOH;*/
  126.                *PacketSizePtr = 128;
  127.                break;
  128.            case STX:
  129.                /* 1024 byte buffer incoming */
  130.                /*PacketType = STX;*/
  131.                *PacketSizePtr = 1024;
  132.                break;
  133.            case CAN:
  134.                 /* sender has canceled ! */
  135.                 DisplayLine("*** Canceled by REMOTE ***",NULL,0);
  136.                 return(FALSE);
  137.            case EOT:
  138.                 /* all packets have been sent */
  139.                 Code = PutChar(Port,ACK);
  140.                 *EOTptr = TRUE;
  141.                 return(TRUE);
  142.            default:
  143.                 /* error ! */
  144.                 sprintf(temp,"Expecting SOH/STX/EOT/CAN not %xH",(char)Code);
  145.                 PacketError(Port,PacketNbr,Attempt,temp);
  146.                 return(FALSE);
  147.           }
  148.       /* receive packet # */
  149.       Code = GetChar(Port,SHORT_WAIT*ONE_SECOND);
  150.       if(Code==-1)
  151.         {PacketError(Port,PacketNbr,Attempt,"timed out waiting for packet number");
  152.          return(FALSE);
  153.         }
  154.       RxPacketNbr = 0x00ff & Code;
  155.       /* receive 1's complement */
  156.       Code = GetChar(Port,SHORT_WAIT*ONE_SECOND);
  157.       if(Code==-1)
  158.         {PacketError(Port,PacketNbr,Attempt,"timed out waiting for complement of packet #");
  159.          return(FALSE);
  160.         }
  161.       RxPacketNbrComp = 0x00ff & Code;
  162.       /* verify packet number */
  163.       if(RxPacketNbr+RxPacketNbrComp!=255)
  164.           {PacketError(Port,PacketNbr,Attempt,"Bad packet number");
  165.            return(FALSE);
  166.           }
  167.       /* receive data */
  168.       CheckSum = 0;
  169.       for(i=0;i<*PacketSizePtr;i++)
  170.           {Code = GetChar(Port,LONG_WAIT*ONE_SECOND);
  171.            if(Code==-1)
  172.                    {PacketError(Port,PacketNbr,Attempt,"timed out waiting for data for packet #");
  173.                     return(FALSE);
  174.                    }
  175.            Buffer[i] = Code;
  176.            /* compute CRC or checksum */
  177.            if(NCGchar!=NAK) CheckSum = UpdateCRC(CheckSum,(unsigned char)Code);
  178.            else CheckSum = (CheckSum + Code) & 0x00ff;
  179.           }
  180.       /* receive CRC/checksum */
  181.       if(NCGchar!=NAK)
  182.           {/* receive 2 byte CRC */
  183.            Code = GetChar(Port,SHORT_WAIT*ONE_SECOND);
  184.            if(Code==-1)
  185.                    {PacketError(Port,PacketNbr,Attempt,"timed out waiting for 1st CRC byte");
  186.                     return(FALSE);
  187.                    }
  188.            RxCheckSum1 = Code & 0x00ff;
  189.            Code = GetChar(Port,SHORT_WAIT*ONE_SECOND);
  190.            if(Code==-1)
  191.                    {PacketError(Port,PacketNbr,Attempt,"timed out waiting for 2nd CRC byte");
  192.                     return(FALSE);
  193.                    }
  194.            RxCheckSum2 = Code & 0x00ff;
  195.            RxCheckSum = (RxCheckSum1<<8) | RxCheckSum2;
  196.           }
  197.       else
  198.           {/* receive one byte checksum */
  199.            Code = GetChar(Port,SHORT_WAIT*ONE_SECOND);
  200.            if(Code==-1)
  201.                    {PacketError(Port,PacketNbr,Attempt,"timed out waiting for checksum");
  202.                     return(FALSE);
  203.                    }
  204.            RxCheckSum = Code & 0x00ff;
  205.           }
  206.       /* don't send ACK if 'G' */
  207.       if(NCGchar=='G') return(TRUE);
  208.       /* checksum OK ? */
  209.       if(RxCheckSum!=CheckSum)
  210.           {DisplayLine("Bad packet checksum",NULL,0);
  211.            Code = PutChar(Port,NAK);
  212.           }
  213.       /* packet number OK ? */
  214.       else if(RxPacketNbr!=PacketNbr)
  215.           {DisplayLine("Bad packet number",NULL,0);
  216.            Code = PutChar(Port,NAK);
  217.           }
  218.       else
  219.           {/* ACK the packet */
  220.            PutChar(Port,ACK);
  221.            return(TRUE);
  222.           } /* end if */
  223.      } /* end -- for(Attempt) */
  224.  /* can't receive packet */
  225.  SayError(Port,"RX packet timeout");
  226.  return(FALSE);
  227. } /* end -- RxPacket */
  228.  
  229. void PacketError(int Port, int Packet, int Attempt, char *MsgPtr)
  230. {char temp[81];
  231.  sprintf(temp,"Packet %d : Attempt %d : %s",Packet,Attempt,MsgPtr);
  232.  SayError(Port,temp);
  233. }
  234.  
  235. int TxStartup(int Port,char *NCGcharPtr)
  236. {int i;
  237.  int Code;
  238. #if DEBUG
  239.  printf("### TxStartup");
  240. #endif
  241.  /* clear Rx buffer */
  242.  SioRxFlush(Port);
  243.  /* wait for receivers start up NAK, 'C', or 'G' */
  244.  for(i=1;i<LIMIT;i++)
  245.      {if(SioKeyPress())
  246.           {SayError(Port,"Aborted by user");
  247.            return(FALSE);
  248.           }
  249.       Code = GetChar(Port,SHORT_WAIT*ONE_SECOND);
  250.       if(Code==-1) continue;
  251.       /* received a byte */
  252.       if((char)Code==NAK)
  253.           {*NCGcharPtr = NAK;
  254. #if DEBUG
  255.            printf("(CS) OK\n");
  256. #endif
  257.            return(TRUE);
  258.           }
  259.       if((char)Code=='C')
  260.           {*NCGcharPtr = 'C';
  261. #if DEBUG
  262.            printf("(CRC) OK\n");
  263. #endif
  264.            return(TRUE);
  265.           }
  266.       if((char)Code=='G')
  267.           {*NCGcharPtr = 'G';
  268. #if DEBUG
  269.            printf("(G) OK\n");
  270. #endif
  271.            return(TRUE);
  272.           }
  273.      } /* end -- for(i) */
  274.  /* no response */
  275.  SayError(Port,"No response from receiver");
  276.  return(FALSE);
  277. } /* end -- TxStartup */
  278.  
  279.  
  280. int RxStartup(int Port,char *NCGcharPtr)
  281. {int i;
  282.  int Code;
  283. #if DEBUG
  284.  printf("### RxStartup");
  285.  printf(" %c[%xH]",*NCGcharPtr,*NCGcharPtr);
  286. #endif
  287.  /* clear Rx buffer */
  288.  SioRxFlush(Port);
  289.  /* Send NAKs, 'C's, or 'G's */
  290.  for(i=1;i<LIMIT;i++)
  291.      {if(SioKeyPress())
  292.           {DisplayLine("*** Canceled by USER ***",NULL,0);
  293.            return(FALSE);
  294.           }
  295.       /* stop attempting CRC/'G' after 1st 4 tries */
  296.       if((*NCGcharPtr!=NAK)&&(i==5)) *NCGcharPtr = NAK;
  297.       /* tell sender that I am ready to receive */
  298.       Code = PutChar(Port,*NCGcharPtr);
  299.       Code = GetChar(Port,SHORT_WAIT*ONE_SECOND);
  300.       if(Code==-1) continue;
  301.       /* no error -- must be incoming byte -- push byte back onto queue ! */
  302.       SioUnGetc(Port,(char)Code);
  303. #if DEBUG
  304.       printf("OK\n");
  305. #endif
  306.       return(TRUE);
  307.      } /* end -- for(i) */
  308.  /* no response */
  309.  SayError(Port,"No response from sender");
  310.  return(FALSE);
  311. } /* end -- RxStartup */
  312.  
  313. int TxEOT(int Port)
  314. {int i;
  315.  int Code;
  316.  for(i=0;i<10;i++)
  317.      {Code = PutChar(Port,EOT);
  318.       /* await response */
  319.       Code = GetChar(Port,SHORT_WAIT*ONE_SECOND);
  320.       if((char)Code==ACK) return(TRUE);
  321.      } /* end -- for(i) */
  322.   return(FALSE);
  323.  } /* end -- TxEOT */